use serde::{Deserialize, Serialize};
use std::fmt::{Debug, Display};
use validator::Validate;

pub const LIMIT_MAX: u64 = 200;

#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
pub struct Event<T> {
    pub event_type: String,
    pub payload: T,
}

#[derive(Serialize, Deserialize, Debug, Clone, Default, Eq, PartialEq)]
pub struct ResponseCode(pub i32);

impl ResponseCode {
    pub const OK: Self = Self(200);
    pub const BAD_REQUEST: Self = Self(400);
    pub const UNAUTHORIZED: Self = Self(401);
    pub const NOT_FOUND: Self = Self(404);
    pub const INTERNAL_ERROR: Self = Self(500);

    pub fn is_success(&self) -> bool {
        self.0 == Self::OK.0
    }
}

impl Display for ResponseCode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str(self.0.to_string().as_str())
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Response<T> {
    pub code: ResponseCode,
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub message: String,
    pub data: T,
}

impl<T> Response<T> {
    pub const MESSAGE_INTERNAL_ERROR: &'static str = "内部错误";
    pub fn new_ok(data: T) -> Self {
        Self {
            code: ResponseCode::OK,
            message: "".to_string(),
            data,
        }
    }
}

impl Response<()> {
    pub fn new(code: ResponseCode, message: String) -> Self {
        Self {
            code,
            message,
            data: (),
        }
    }

    pub fn internal_error() -> Self {
        Self::new(
            ResponseCode::INTERNAL_ERROR,
            Self::MESSAGE_INTERNAL_ERROR.to_string(),
        )
    }
}

pub fn new_ok_response() -> Response<()> {
    Response {
        code: ResponseCode::OK,
        message: "".to_string(),
        data: (),
    }
}

#[derive(Serialize, Deserialize, Validate, Debug, Clone)]
pub struct ListRequest<T>
where
    T: Debug + Default + Clone + PartialEq,
{
    pub offset: u64,
    #[validate(range(max = LIMIT_MAX))]
    pub limit: u64,
    #[serde(default)]
    pub filter: T,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ListResponseData<T> {
    pub total_count: u64,
    pub list: Vec<T>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct AllResponseData<T> {
    pub list: Vec<T>,
}

#[derive(Serialize, Deserialize, Validate, Debug, Clone, Default)]
pub struct ExistsRequest<T> {
    pub filter: T,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ExistsResponseData {
    pub exists: bool,
}

#[derive(Serialize, Deserialize, Validate, Debug, Clone, Default)]
pub struct DeleteByFilter<T> {
    pub filter: T,
}